#ifndef _LOG_API_H_
#define _LOG_API_H_

#include <string.h>
#include <stdint.h>
#include <stdbool.h>

// 日志上限
#define LOG_LIMIT                      (1000ul)
// 日志报文长度
#define LOG_DATA_PACKET_LENGTH         (USER_AUTHENTICATION_KEY_LENGTH)

/**
 * @brief 持卡人验证状态
 *
 */
typedef enum
{
  CARDHOLDER_AUTHECTICATION_ERROR      = 0x00, // 鉴权失败
  CARDHOLDER_AUTHENTICATION_SUCCESS    = 0x01, // 鉴权成功
  CARDHOLDER_FORBIDDEN                 = 0x02, // 持卡人已禁用
  CARDHOLDER_OUT_OF_DATE               = 0x03, // 不在有效期内
} CardHolderVerifyStatus_t;

/**
 * @brief 日志事件类型
 *
 */
typedef enum
{
  LOG_PHYSICAL_CARD_NUMBER             = 0x00, // 物理卡号
  LOG_CALIBRATION_TIME_CARD            = 0x01, // 校准时间卡
  LOG_GUEST_ROOM_CARD                  = 0x02, // 宾客房卡
  LOG_MASTER_ROOM_CARD                 = 0x03, // 总卡
  LOG_BUILD_ROOM_CARD                  = 0x04, // 楼栋卡
  LOG_FLOOR_ROOM_CARD                  = 0x05, // 楼层卡
  LOG_CLEANING_STAFF_CARD              = 0x06, // 保洁人员卡
  LOG_PARK_ROOM_CARD                   = 0x07, // 园区卡
  LOG_CLEAR_PARAMETER_CARD             = 0x09, // 清除卡
  LOG_BLUETOOTH_VIRTUAL_CARD_NUMBER    = 0x0A, // 蓝牙虚拟卡号
  LOG_USER_KEYSCANF_PASSWORD           = 0x10, // 密码
  LOG_QR_CODE_SCANF                    = 0x20, // 二维码
  LOG_FINGER_SCANF                     = 0x30, // 指纹
  LOG_FACE_SCANF                       = 0x40, // 人脸
  LOG_COMMAND_OPEN_DOOR                = 0x50, // 命令开锁
  LOG_EXIT_BUTTON                      = 0x51, // 出门按钮
  LOG_NEW_CARDHOLDER                   = 0x70, // 新增持卡人
  LOG_CHANGE_CARDHOLDER                = 0x71, // 修改持卡人
  LOG_DELETE_CARDHOLDER                = 0x72, // 删除持卡人
  LOG_ANTI_SKID_ALARM                  = 0xE1, // 防撬警报
  LOG_FALSE_LOCK_ALARM                 = 0xE2, // 假锁
  LOG_DOUBLE_LOCK_ALARM                = 0xE3, // 反锁
  LOG_DOOR_CONTACT_ALRAM               = 0xE4, // 门磁
  LOG_UNLOCK_WITH_KEY                  = 0xE5, // 钥匙开锁
  LOG_NORMAL_OPEN                      = 0xE6, // 常开
  LOG_FIRMWARE_UPGRADE                 = 0xED, // 固件更新
  LOG_DEVICE_STARTUP                    = 0xEE, // 设备重启
} EventTypeSubCmd_t;

#pragma pack(push, 1)

/**
 * @brief 日志文件表
 *
 */
typedef struct
{
  uint8_t Time[4];                            // 触发时间
  uint8_t EventType;                          // 事件类型
  uint8_t AttachParam;                        // 附带状态
  uint8_t DataPacket[LOG_DATA_PACKET_LENGTH]; // 附带数据
} LogDataSheet_t;

/**
 * @brief 日志文件属性
 *
 */
typedef struct
{
  uint16_t Quantity;    // 数量
  uint16_t WriteOffset; // 写入偏移
} LogFileAttribute_t;

#pragma pack(pop)

/**
 * @brief 写物理卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WritePhysicalCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写校时卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteCalibrationCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写宾客卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteGuestCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写总卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteMasterCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写楼栋卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteBuildCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写楼层卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteFloorCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写保洁卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteCleaningStaffCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写应急卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteParkCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写清除密钥卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteClearTheKeyLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写蓝牙虚拟卡日志信息
 *
 * @param pCardNumberIn - 卡号
 * @param NumberOfCard  - 卡号长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteBluetoothVirtualCardOpenDoorLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status);

/**
 * @brief 写二维码开锁执行结果日志信息
 *
 * @param pDataIn   - 二维码附带数据
 * @param DataSize  - 二维码数据长度
 * @param Status    - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteQrcodeUnlockExecuteResultLog(const void *pDataIn, const uint8_t DataSize, const uint8_t Status);

/**
 * @brief 写键盘键入密钥日志信息
 *
 * @param pUserTokenIn  - 用户令牌
 * @param NumberOfToken - 用户令牌数据长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteKeyboardScanfLog(const void *pUserTokenIn, uint8_t NumberOfToken, const uint8_t Status);

/**
 * @brief 写指纹识别验证信息
 *
 * @param pUserTokenIn  - 用户令牌
 * @param NumberOfToken - 用户令牌数据长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteFingerprintVerificationLog(const void *pUserTokenIn, uint8_t NumberOfToken, const uint8_t Status);

/**
 * @brief 写人脸识别验证日志信息
 *
 * @param pUserTokenIn  - 用户令牌
 * @param NumberOfToken - 用户令牌数据长度
 * @param Status        - 验证状态
 * @return uint16_t     - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteFaceVerificationLog(const void *pUserTokenIn, uint8_t NumberOfToken, const uint8_t Status);

/**
 * @brief 写命令开锁执行结果日志信息
 *
 * @param pDataIn   - 附带信息
 * @param DataSize  - 附带信息长度
 * @param Status    - 验证状态
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteCommandUnlockExecuteResultLog(const void *pDataIn, const uint8_t DataSize, const uint8_t Status);

/**
 * @brief 写新增持卡人日志信息
 *
 * @param KeyType     -  密钥类型
 * @param pKeyValueIn -  密钥
 * @param NumberOfKey -  密钥长度
 * @return uint16_t   - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteAddNewCardholderLog(const uint8_t KeyType, const void *pKeyValueIn, const uint8_t NumberOfKey);

/**
 * @brief 写修改持卡人日志信息
 *
 * @param KeyType     - 密钥类型
 * @param pKeyValueIn - 密钥
 * @param NumberOfKey - 密钥长度
 * @return uint16_t   - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteChangeTheCardholderLog(const uint8_t KeyType, const void *pKeyValueIn, const uint8_t NumberOfKey);

/**
 * @brief 删除持卡人日志信息
 *
 * @param KeyType     - 密钥类型
 * @param pKeyValueIn - 密钥
 * @param NumberOfKey - 密钥长度
 * @return uint16_t   - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteDeleteTheCardholderLog(const uint8_t KeyType, const void *pKeyValueIn, const uint8_t NumberOfKey);

/**
 * @brief 写防撬触发状态日志信息
 *
 * @param Status    - 防撬触发状态
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteAntiSkidAlarmLog(bool Status);

/**
 * @brief 写假锁触发状态日志信息
 *
 * @param Status    - 假锁触发状态
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteFalseLookAlarmLog(bool Status);

/**
 * @brief 写反锁触发状态日志信息
 *
 * @param Status    - 反锁触发状态
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteDoubleLookAlarmLog(bool Status);

/**
 * @brief 写门磁触发状态日志信息
 *
 * @param Status    - 门磁触发状态
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteDoorContactAlarmLog(bool Status);

/**
 * @brief 写钥匙开锁日志
 *
 */
extern uint16_t WriteKeyUnlockLog(void);

/**
 * @brief 写常开触发状态日志
 *
 * @param Status    - 常开触发状态
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteNormalOpenLog(bool Status);

/**
 * @brief 写固件升级日志信息
 *
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteFirmwareUpgradeLog(void);

/**
 * @brief 写设备上电日志信息
 *
 * @return uint16_t - 写入日志表对应编码（0无效）
 */
extern uint16_t WriteDeviceStartupLog(void);

/**
 * @brief 初始化日志功能
 *
 */
extern void InitialisationLogFile(void);

/**
 * @brief 获取日志堆栈深度
 *
 * @return uint16_t - 堆栈深度
 */
extern uint16_t GetLogStackDepth(void);

/**
 * @brief 获取目标编码的日志文件信息
 *
 * @param TargetTableId    - 目标日志表编码
 * @param pLogFileSheetOut - 输入日志表文件信息
 */
extern void GetLogFileInformationForTheTargetCode(uint16_t TargetTableId, LogDataSheet_t *pLogFileSheetOut);

#endif
